﻿using Furion;
using SqlSugar;
using System.Collections.Concurrent;
using System.Collections;
using System.Linq.Expressions;
using System.Reflection;
using NewLife.Caching;
using HiSportApplet.Core.Const;
using HiSportApplet.Core.Extension;

namespace HiSportApplet.Application.Common.SqlSugar
{

    public static class SqlSugarFilter
    {
        /// <summary>
        /// 缓存全局查询过滤器（内存缓存）
        /// </summary>
        private static readonly ICache _cache = Cache.Default;


        /// <summary>
        /// 配置自定义过滤器
        /// </summary>
        public static void SetCustomEntityFilter(SqlSugarScopeProvider db)
        {
            // 配置自定义缓存
            var cacheKey = $"db:{db.CurrentConnectionConfig.ConfigId}:custom";
            var tableFilterItemList = _cache.Get<List<TableFilterItem<object>>>(cacheKey);
            if (tableFilterItemList == null)
            {
                // 获取自定义实体过滤器
                var entityFilterTypes = App.EffectiveTypes.Where(u => !u.IsInterface && !u.IsAbstract && u.IsClass
                    && u.GetInterfaces().Any(i => i.HasImplementedRawGeneric(typeof(IEntityFilter))));
                if (!entityFilterTypes.Any()) return;

                var tableFilterItems = new List<TableFilterItem<object>>();
                foreach (var entityFilter in entityFilterTypes)
                {
                    var instance = Activator.CreateInstance(entityFilter);
                    var entityFilterMethod = entityFilter.GetMethod("AddEntityFilter");
                    var entityFilters = ((IList)entityFilterMethod?.Invoke(instance, null))?.Cast<object>();
                    if (entityFilters == null) continue;

                    foreach (var u in entityFilters)
                    {
                        var tableFilterItem = (TableFilterItem<object>)u;
                        var entityType = tableFilterItem.GetType().GetProperty("type", BindingFlags.Instance | BindingFlags.NonPublic).GetValue(tableFilterItem, null) as Type;
                        // 排除非当前数据库实体
                        var tAtt = entityType.GetCustomAttribute<TenantAttribute>();
                        if (tAtt != null && db.CurrentConnectionConfig.ConfigId.ToString() != tAtt.configId.ToString() ||
                            tAtt == null && db.CurrentConnectionConfig.ConfigId.ToString() != SqlSugarConst.BaseConfigId)
                            return;

                        tableFilterItems.Add(tableFilterItem);
                        db.QueryFilter.Add(tableFilterItem);
                    }
                }
                _cache.Add(cacheKey, tableFilterItems);
            }
            else
            {
                tableFilterItemList.ForEach(u =>
                {
                    db.QueryFilter.Add(u);
                });
            }
        }
    }

    /// <summary>
    /// 自定义实体过滤器接口
    /// </summary>
    public interface IEntityFilter
    {
        /// <summary>
        /// 实体过滤器
        /// </summary>
        /// <returns></returns>
        IEnumerable<TableFilterItem<object>> AddEntityFilter();
    }
}
